import os
from dotenv import load_dotenv
import can
import threading
import time

try:
    import serial.tools.list_ports
    SERIAL_AVAILABLE = True
except ImportError:
    SERIAL_AVAILABLE = False
    print("注意: pyserial库未安装，无法扫描串口")

# 全局变量用于控制CAN读取器
can_running = False
can_thread = None

def scan_serial_ports():
    """
    扫描系统中所有可用的串口并输出到控制台
    """
    if not SERIAL_AVAILABLE:
        print("无法扫描串口: pyserial库未安装")
        return []
    
    print("正在扫描系统中的串口...")
    ports = list(serial.tools.list_ports.comports())
    
    if not ports:
        print("未找到可用的串口")
        return []
    
    print(f"找到 {len(ports)} 个串口:")
    print("-" * 50)
    
    for i, port in enumerate(ports):
        print(f"{i+1}. 端口: {port.device}")
        print(f"   描述: {port.description}")
        print(f"   硬件ID: {port.hwid}")
        if port.vid:
            print(f"   VID: {hex(port.vid)}")
        if port.pid:
            print(f"   PID: {hex(port.pid)}")
        print("-" * 50)
    
    return ports

def read_can_data():
    global can_running
    # 加载 .env 文件中的配置
    load_dotenv()
    
    # 从 .env 文件中读取串口配置
    interface = os.getenv('CAN_INTERFACE', 'socketcan')
    channel = os.getenv('CAN_CHANNEL', 'can0')
    bitrate = os.getenv('CAN_BITRATE', '500000')
    
    bus = None
    try:
        # 创建 CAN 总线连接
        # 尝试使用新版本API
        try:
            bus = can.Bus(interface=interface, channel=channel, bitrate=int(bitrate))
        except (AttributeError, TypeError):
            # 如果新版本API不可用，使用旧版本API
            bus = can.Bus(bustype=interface, channel=channel, bitrate=int(bitrate))
        
        print(f"成功连接到 CAN 接口: {interface}, 通道: {channel}, 波特率: {bitrate}")
        
        # 读取 CAN 数据
        can_running = True
        while can_running:
            try:
                message = bus.recv(timeout=1.0)
                if message is not None:
                    # 检查消息是否有效
                    if hasattr(message, 'dlc') and message.dlc <= 8:
                        print(f"接收到消息: {message}")
                    else:
                        print(f"警告: 接收到无效的CAN消息 (DLC={getattr(message, 'dlc', 'unknown')}): {message}")
            except can.CanError as e:
                error_msg = str(e)
                if "DLC" in error_msg or "data length" in error_msg.lower():
                    print(f"警告: 接收到无效的CAN消息 - {e}")
                    continue
                else:
                    print(f"CAN错误: {e}")
                    break
            except Exception as e:
                print(f"发生错误: {e}")
                break
    except Exception as e:
        error_msg = str(e)
        if "DLC" in error_msg or "data length" in error_msg.lower():
            print(f"警告: CAN接口配置错误 - {e}")
            print("可能的原因:")
            print("1. 波特率设置不正确")
            print("2. 串口设备不支持CAN协议")
            print("3. 串口设备发送的数据格式不正确")
        else:
            print(f"发生错误: {e}")
    finally:
        can_running = False
        if bus:
            bus.shutdown()
        print("CAN读取器已停止")

def start_can_reader():
    """
    启动CAN读取器线程
    """
    global can_thread, can_running
    if not can_running:
        can_thread = threading.Thread(target=read_can_data, daemon=True)
        can_thread.start()
        print("CAN读取器已启动")
        return True
    else:
        print("CAN读取器已在运行")
        return False

def stop_can_reader():
    """
    停止CAN读取器
    """
    global can_running
    can_running = False
    print("正在停止CAN读取器...")

if __name__ == "__main__":
    # 首先扫描所有串口
    scan_serial_ports()
    
    # 启动CAN读取器
    start_can_reader()
    try:
        # 主线程保持运行
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        stop_can_reader()